/************************************************************************/
/*    Author: Scott Bevin                                               */
/************************************************************************/


#include "CEGuiDebuggingTools.h"
#include "CEGuiDebugMessageLogger.h"

namespace XF
{
	CEGuiDebuggingTools::CEGuiDebuggingTools(Application* ownerApp, std::string skinFile)
		: SystemComponent(ownerApp), mSkinFile(skinFile), mButtonWidth(100), mButtonHeight(20), mSpacing(5)
	{
	}

	CEGuiDebuggingTools::~CEGuiDebuggingTools()
	{
	}

	bool CEGuiDebuggingTools::OnInitialise()
	{
		mGui = NULL;

		PostAMessage(
			XF::MailingList::GUI_SUBSYSTEM,
			XF::MessageSubject::PLEASE_SEND_GUI,
			NULL);	
		
		if(!mGui)
		{
			ILOG << "ERROR getting GUI CEGuiDebuggingTools::OnInitialise";
			return false;
		}
		mDebugRoot = mGui->CreateBlankSheet("DebugToolsRoot");
		if(!mDebugRoot)return false;

		CreateDebugWindow();

		RegisterTool("VariableTrackerWindow", "Variables", new CEGuiDebugVariableTrackerWindow());
		RegisterTool("MessageLoggerWindow", "Logger", new CEGuiDebugMessageLogger());

		return true;
	}

	void CEGuiDebuggingTools::OnShutDown()
	{
		for(ToolsMapIt it = mTools.begin();
			it != mTools.end();)
		{
			std::string toolName = it->first;

			++it;

			DestroyTool(toolName);
		}

		mGui->KillWindow(mDebugRoot);
	}

	bool CEGuiDebuggingTools::OnHandleMessage( const Message &message )
	{
		switch(message.Subject)
		{
		case MessageSubject::SENT_GUI:
			{
				mGui = static_cast<CEGUIComponent*>(message.Data);
				return true;
			}
		}
		return false;
	}

	void CEGuiDebuggingTools::CreateDebugWindow()
	{
		mWindow = mGui->CreateFrameWindow("CEGuiDebuggingToolsWindow");//chris: updated this as a test, works fine
		//(CEGUI::FrameWindow*)CEGUI::WindowManager::getSingletonPtr()->createWindow(mSkinFile + "/FrameWindow", "CEGuiDebuggingToolsWindow");
		mWindow->setText("XFramework Debugging Tools");
		mWindow->setVisible(true);
		mWindow->setPosition(CEGUI::UVector2(CEGUI::UDim(0, 0), CEGUI::UDim(0, 0)));
		mWindow->setSize(CEGUI::UVector2(CEGUI::UDim(1, 0), CEGUI::UDim(0, 40)));
		mWindow->setAlpha(0.5f);
		mWindow->setSizingEnabled(false);
		mWindow->setDragMovingEnabled(true);
		//mWindow->setAlwaysOnTop(true);
		mWindow->setCloseButtonEnabled(false);

		mGui->LinkEvent(
			mWindow->getTitlebar()->getName(), 
			new CEGUI::Event::Subscriber(&CEGuiDebuggingTools::TitlebarDoubleClicked, this), 
			CEGUI::Titlebar::EventMouseDoubleClick);

		mDebugRoot->addChildWindow(mWindow);
	}

	void CEGuiDebuggingTools::RegisterTool( std::string name, std::string buttonText, CEGuiDebuggerTool* tool )
	{
		tool->Initialize(mGui, mSkinFile, mDebugRoot);

		/*CEGUI::ButtonBase *button =  (CEGUI::ButtonBase*)CEGUI::WindowManager::getSingletonPtr()->createWindow(mSkinFile + "/Button",  "DebugingToolsButton" + name);
		button->setText(buttonText);
		button->setSize(CEGUI::UVector2(CEGUI::UDim(0, mButtonWidth), CEGUI::UDim(0, mButtonHeight)));
		button->setYPosition(CEGUI::UDim(0, 30));
		CEGUI::String fullname = "DebugingToolsButton" + name;
		mGui->LinkEvent(fullname, new CEGUI::Event::Subscriber(&CEGuiDebuggingTools::ButtonClicked, this));
		
	
		mWindow->addChildWindow(button);*/

		//Chris: updated this function to use components create button method
		CEGUI::ButtonBase *button = mGui->CreateButtonA("DebugingToolsButton" + name,
														buttonText,
														mButtonWidth,mButtonHeight,
														0,0.5,
														new CEGUI::Event::Subscriber(&CEGuiDebuggingTools::ButtonClicked, this));
		mWindow->addChildWindow(button);
		mTools.insert(std::make_pair(name, std::make_pair(button, tool)));

		RejigPositioning();
	}

	void CEGuiDebuggingTools::DestroyTool( std::string name )
	{
		CEGuiDebuggerTool *tool = mTools[name].second;

		tool->ShutDown();
		delete tool;

		CEGUI::WindowManager::getSingletonPtr()->destroyWindow(mTools[name].first->getName());
		mTools.erase(name);

		RejigPositioning();
	}

	void CEGuiDebuggingTools::RejigPositioning()
	{
		int count = 0;

		for(ToolsMapIt it = mTools.begin();
			it != mTools.end(); ++it)
		{
			CEGUI::ButtonBase *button = it->second.first;

			button->setXPosition(CEGUI::UDim(0, (mButtonWidth * count) + (mSpacing * count) + (mSpacing * 2)));

			++count;
		}
	}

	bool CEGuiDebuggingTools::ButtonClicked( const CEGUI::EventArgs &args )
	{
		const CEGUI::WindowEventArgs& we = static_cast<const CEGUI::WindowEventArgs&>(args);

		for(ToolsMapIt it = mTools.begin();
			it != mTools.end(); ++it)
		{
			if(it->second.first == (CEGUI::ButtonBase*)we.window)
			{
				if(it->second.second->IsVisible())
					it->second.second->Hide();
				else
				{
					it->second.second->Show();
				}

				return true;
			}
		}

		return false;
	}

	bool CEGuiDebuggingTools::TitlebarDoubleClicked( const CEGUI::EventArgs &args )
	{

		return true;
	}

	void CEGuiDebuggingTools::OnHandleInput( double dT, Input *input )
	{
		if(input->IsKeyPress(OIS::KC_F12))
		{
			this->mDebugRoot->setVisible(!this->mDebugRoot->isVisible());
		}
	}
}
